package p2pcdnsim.report;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import desmoj.core.simulator.Model;

public class Bandwidth extends desmoj.core.statistic.Histogram {

	private List<Item> items;
	
    private Map<String,Integer> map;

	public Bandwidth(Model ownerModel, String name,boolean showInReport, boolean showInTrace) {
		super(ownerModel, name, 0,0,1, showInReport, showInTrace);
		items = new ArrayList<Item>();
		map = new HashMap<String, Integer>();
	}

	@Override
	public desmoj.core.report.Reporter createReporter() {
		return new BandwidthReporter(this);
	}

	public int getNumberItems() {
		return items.size();
	}
	
    public String getItem(int i) {
        return this.items.get(i).item;
    }

	public long getObservationsForItem(int index) {
		if (index < 0 || index >= items.size()) {
			sendWarning("Attempt to get the number of observations from a not "
					+ "known item. Zero (0) will be returned!", "HistogramText: "
					+ this.getName() + " Method: getObservationsForItem"
					+ "( int index ).",
					"The passed int: index in this method is negative or greater than "
							+ "the largest item index.",
					"Make sure to ask for the number of observations only for valid "
							+ "indices.");

			return 0; 
		}
		return this.items.get(index).val;
	}

	@Override
	public void reset() {
		super.reset();
		items.clear();
		map.clear();
	}

    public void update(String item, long val) {
        if(!map.containsKey(item)) {
        	Item i = new Item();
        	i.item = item;
        	i.val = 0;
        	items.add(i);
        	map.put(item, items.indexOf(i));
        }
        
        Item i = items.get(map.get(item));
        i.val+=val;
        this.incrementObservations(val);
    }
    
    public void sortItems() {
    	Collections.sort(items);
    }
    
    private class Item implements Comparable<Item> {
    	String item;
    	long val;
    	
		@Override
		public boolean equals(Object obj) {
			return item.equals(((Item)obj).item);
		}

		@Override
		public int compareTo(Item o) {
			return item.compareTo(o.item);
		}
    }
}
